<?php
declare(strict_types=1);
namespace Service\GoodsService;
use Service\BaseService;
use Service\Code\Normal;
use App\Model\BbcModel\Mnuser;
use App\Model\BbcModel\Goods;
use App\Model\BbcModel\CashGoodsChange;
use App\Model\BbcModel\MnStoreGoods;
use Service\ConfigureService\ChannelConfigService;
use Hyperf\DbConnection\Db;
use Service\CacheService\CacheProviderService;
use Service\OrderService\CashOrderService;
use Service\UserService\MnUserService;
use Service\GoodsClassService\ClassService;

/**
 * 收银机商品服务中心
 * @author chenshubo
 */
class CashGoodsService extends BaseService
{
    const CACHE_CLASS_KEY   = 'cache_global_class_key';
    const CACHE_CLASS_TIME  = 30;
    
    /**
     * 店铺分类
     * @param int $cid
     * @param int $mn_sid
     * @param array $body
     * @return mixed
     */
    public function getGlobalClass(int $cid,int $mn_sid,array $body = [])
    {
        $sid        = config('sid')??getSID();
        $mn_user    = Mnuser::instance()->info(['id'=>$mn_sid,'status'=>1,'new_store'=>1]);
        if(empty($mn_user)){
            return Normal::returnCode(Normal::FAIL,'q店不存在');
        }
        
        $mn_channel_id = $mn_user['pid'];
        if(empty($mn_channel_id)){
            return Normal::returnCode(Normal::FAIL,'渠道ID未配置');
        }
        
        $show_class_tree = CacheProviderService::getCacheByKey(self::CACHE_CLASS_KEY);
        if( !empty($show_class_tree) ) {
            return Normal::returnCode(Normal::SUC,'获取成功',$show_class_tree);
        }
        
        $table = Goods::instance()->getTable();
        $class = Goods::instance()
        ->from("{$table} as g")
        ->select([
            Db::raw('DISTINCT g.class_id as third_class_id')
        ])
        ->leftJoin("ly_mn_store_goods as msg",function($join) use ($mn_sid){
            $join->on("msg.goods_id","=","g.id")
            ->where("msg.mn_sid",$mn_sid);
        })
        ->where('g.cid',$mn_channel_id)
        ->where('g.sid',$sid)
        ->get()
        ->toArray();
        $goodsAllClassList = ChannelGoodsClassService::instance()->getGoodsClass($cid);
        $goodsAllClassTree = tree($goodsAllClassList,'0','id','pid');
        $show_class_tree = [];
        if( !empty($class) ) {
            $class_ids = array_column($class,'third_class_id');
            $classList = ChannelGoodsClassService::instance()->getGoodsClassByThirdClassIDs((int)$cid,$class_ids);
            foreach ($goodsAllClassTree as $first)
            {
                $son = [];
                if( !empty($first['son']) ) {
                    foreach ($first['son'] as $second)
                    {
                        $son1 = [];
                        if( !empty($second['son']) ) 
                        {
                            foreach ($second['son'] as $third)
                            {
                                if ( in_array($third['id'],$class_ids)) 
                                {
                                    $son1[] = $third;
                                }
                            }
                        }
                        if (in_array($second['id'],$class_ids) || count($son1) > 0) 
                        {
                            $son[] = $second;
                        }
                    }
                }
                
                $first['son'] = $son;
                if (in_array($first['id'],$class_ids) || count($son) > 0) {
                    $show_class_tree[] = $first;
                }
            }
        }
        
        CacheProviderService::cacheBySetKeyValue(self::CACHE_CLASS_KEY,$show_class_tree,self::CACHE_CLASS_TIME);
        return Normal::returnCode(Normal::SUC,"获取成功",$show_class_tree);
    }
    
    /**
     * 获取店铺商品分页数据
     * @param int $cid
     * @param int $mn_sid
     * @param array $body
     * @return mixed
     */
    public function getGoodslist(int $cid,int $mn_sid,array $body = [])
    {
        $page       = $body['page'] ?? 1;
        $limit      = $body['limit'] ??10;
        $mn_user    = MnUserService::getMnUserInfoByMnSid($mn_sid);
        $mn_user_type = $mn_user['type'];
        $mn_level     = $mn_user['level'];
        $select = [
            'msg.*',
            'g.name',
            'g.skucode',
            'g.barcode',
            'g.price_store',
            'g.class_id',
            'g.img',
            'g.body',
            'g.cid',
            'gc.name as classname',
            'g.origin',
            'g.is_bonded',
            'g.tax_rate',
            'g.tax_free',
            'gb.name as brandname',
            'g.brand_id',
            'g.is_combine_goods',
            'g.combine_goods_json_body',
            'g.high_price',
            'g.high_tax_rate',
            'g.tax_free',
        ];
        
        $table = MnStoreGoods::instance()->getTable();
        $query = MnStoreGoods::instance()
        ->from("{$table} as msg")
        ->join('ly_goods as g','msg.goods_id','=','g.id')
        ->leftjoin('ly_goods_class as gc','gc.id','=','g.class_id')
        ->leftjoin('ly_goods_brand as gb','gb.id','=','g.brand_id');

        //0.9.38.2 收银机不展示门店已删除且可用库存=0的商品
        $query->whereRaw('(msg.df=0 and (msg.quantity <> 0 or msg.num <> 0))' );

        //根据最新的时间查询收银机商品数据,否则就是初始化全量数据
        if( isset($body['last_time']) && is_numeric($body['last_time']) )
        {
            $subQuery = CashGoodsChange::instance()
            ->select(['goods_id'])
            ->where('cid',$cid)
            ->where('mn_sid',$mn_sid)
            ->where('cd','>=',$body['last_time'])
            ->groupBy('goods_id');
            $query->joinSub($subQuery,"cash_change",function($join){
                $join->on('cash_change.goods_id', '=', 'g.id');
            });
        }
        $query->where('msg.storestatus',1)
        ->where('msg.mn_sid',$mn_sid);
        
        //前置仓库
        if( $mn_user_type == Mnuser::TYPE_STORE_QZ ) {
//            $query->where(function($query)
//            {
//                $query->orWhere(function($query){
//                    $query->whereIn('g.is_bonded',['0','3'])
//                    ->where('g.df',0)
//                    ->where('g.status',1)
//                    ->where('g.is_trade',1);
//                })
//                ->orWhere(function($query){
//                    $query->where('g.is_bonded',1)
//                    ->where('g.df',0)
//                    ->where('g.status',1)
//                    ->where('msg.bonded_store',1);
//                });
//            });
            
             /*$query->where('g.is_bonded',1)
                    ->where('g.df',0)
                    ->where('g.status',1)
                    ->where('msg.bonded_store',1);*/

            //前置仓收银机可以下单代发的一般贸易和保税商品
            $query->where('g.df',0)
                ->where('g.status',1)
                ->where(function($query){
                    $query->where(['g.is_bonded'=>0,'g.is_trade' => 0])
                        ->orWhere(['msg.bonded_store'=>1]);
                });
        } else {
            $query->whereIn('g.is_bonded',['0','3'])->where('g.is_trade',1);
        }
        
        if(isset($body['barcode']) && $body['barcode']!=''){
            $query->where('g.barcode',$body['barcode']);
        }
        
        if(isset($body['skucode']) && $body['skucode']!=''){
            $query->where('g.skucode',$body['skucode']);
        }
        
        if(isset($body['class_id']) && $body['class_id']!=''){
            $goodsAllClassList = ChannelGoodsClassService::instance()->getGoodsClass($cid);
            $goodsAllChildClass = all_sub($goodsAllClassList,$body['class_id'],'id','pid');
            $classIds=[$body['class_id']];
            if(!empty($goodsAllChildClass)){
                $goodsAllChildClassIDS= array_column($goodsAllChildClass, 'id');
                $classIds= array_merge($classIds,$goodsAllChildClassIDS);
            }
            $query->whereIn('g.class_id',$classIds);
        }
        
        if ( isset($body['search']) && !empty($body['search']) ) {
            $search = $body['search'];
            $query->where(function($query) use ($search)
            {
                $query->orWhere('g.skucode','like',"%{$search}%")
                ->orWhere('g.barcode','like',"%{$search}%")
                ->orWhere('g.name','like',"%{$search}%");
            });
        }
        
        if( isset($body['goodsids']) && !empty($body['goodsids']) ){
            $goodsids= explode(',', $body['goodsids']);
            $query->whereIn('g.id',$goodsids);
        }
        
        $pageInfo = $query->paginate((int)$limit,$select, 'page', (int)$page,true)->toArray();
        $list = $pageInfo['data'];
        
        //获取价格设置配置
        $settingPriceConfig = ChannelConfigService::instance()->getChannelConfig('price_decimal',$cid);
        $settingPrice = $settingPriceConfig['price'] ?? 0 ;
        
        //计算商品收益率
        $goodsIds = array_column($list,'goods_id');
        $profitGoodsPriceLists = MnGoodsService::instance()->getGoodsAllProfit($mn_sid, $goodsIds,1,$mn_level);
        $profitGoodsPriceListMap = array_column($profitGoodsPriceLists,null,'goods_id');
        
        //商品批次
        $goodsBatchList = GoodsBatchService::instance()->getGoodsBatchList($mn_sid, $goodsIds);
        $goodsBatchListMap = GoodsBatchService::instance()->getMapList($goodsBatchList);
        
        $data   = [];
        foreach ($list as $key => $value) 
        {
            $goods_id               = $value['goods_id'];
            $profit                 = $profitGoodsPriceListMap[$goods_id] ?? [];
            $value['price_store']   = $profit['price_store'] ?? '0.00';
            $price                  = bcadd((string)$value['price_store'],(string)$profit['profit']?? '0.00',2);
            $price_vip              = bcadd((string)$value['price_store'],(string)$profit['profit_vip']?? '0.00',2);
            $price_tax              =0;
            $price_vip_tax          =0;
            $price_total            =$price;
            $price_vip_total        =$price_vip;
            
            if( $value['is_bonded']==1) 
            {

                if($value['is_combine_goods'] == 1){ //组合商品
                    $single_goods              = $value;
                    $single_goods['price_pay'] = $price; //普通用户单价
                    $combine_goods             = (new CashOrderService())->combineGoodsTaxFee($cid, $single_goods, 1);
                    $price_tax                 = $combine_goods['price_total_tax'];//销售税金
                    $price                     = $price - $price_tax;


                    $single_goods['price_pay'] = $price_vip; //会员用户单价
                    $combine_goods             = (new CashOrderService())->combineGoodsTaxFee($cid, $single_goods);
                    $price_vip_tax             = $combine_goods['price_total_tax'];//销售税金
                    $price_vip                 = $price_vip - $price_vip_tax;

                }else{

                    if( $value['tax_free']== 0 ) {
                        $price_tax          = bcmul((string)$price, (string)$value['tax_rate'],3);
                        $price_vip_tax      = bcmul((string)$price_vip, (string)$value['tax_rate'],3);
                        $price_tax          = number_format((float)$price_tax,2,'.','');
                        $price_vip_tax      = number_format((float)$price_vip_tax,2,'.','');
                        $price_total        = bcadd((string)$price_tax, (string)$price,2);
                        $price_vip_total    = bcadd((string)$price_vip_tax,(string) $price_vip,2);
                    }else{

                        /*$taxflag            = bcadd('1', (string)$value['tax_rate'],3);
                        $price              = bcdiv((string)$price, (string)$taxflag, 3);
                        $price_vip          = bcdiv((string)$price_vip, (string)$taxflag, 3);
                        $price              = number_format((float)$price,2,'.','');
                        $price_vip          = number_format((float)$price_vip,2,'.','');*/
//                        $price_tax          = bcsub((string)$price_total, (string)$price,2);
//                        $price_vip_tax      = bcsub((string)$price_vip_total, (string)$price_vip,2);

                        $price_tax = $this->singGoodsPriceFree($price,$value);
                        $price = $price - $price_tax;

                        $price_vip_tax = $this->singGoodsPriceFree($price_vip,$value);
                        $price_vip = $price_vip - $price_vip_tax;

                        $price_total        = bcadd((string)$price, (string)$price_tax,2);
                        $price_vip_total    = bcadd((string)$price_vip_tax,(string) $price_vip,2);
                    }
                }
//                if( $value['tax_free']== 0 ) {
//                    $price      = bcadd($price, bcmul($price, $value['tax_rate'],2),2);
//                    $price_vip  = bcadd($price_vip, bcmul($price_vip, $value['tax_rate'],2),2);
//                }
//                if( $settingPrice == 0 ) {
//                    $price          = upDecimal($price,1);
//                    $price_vip      = upDecimal($price_vip,1);
//                } else {
//                    $price          = ceil($price);
//                    $price_vip      = ceil($price_vip);
//                }
            }
            
            $data[$key] = [
                'goods_id'          => $value['goods_id'],
                'mn_store_goods_id' => $value['id'],
                'name'              => $value['name'],
                'skucode'           => $value['skucode'],
                'barcode'           => $value['barcode'],
                'storestatus'       => $value['storestatus'],
                'price'             => $price,
                'stock'             => $value['quantity'],
                'onlinestock'       => $value['num'],
                'onlinequantity'    => $value['onlinequantity'],
                'price_vip'         => $price_vip,
                'class_id'          => $value['class_id'],
                'class_name'        => $value['classname'],
                'brand_id'          => $value['brand_id'],
                'brand_name'        => $value['brandname'],
                'img'               => $value['img'],
                'body'              => $value['body'],
                'origin'            => $value['origin'],
                'is_bonded'         => $value['is_bonded'],
                'batch'             => $goodsBatchListMap[$goods_id] ?? [],
                'tax_rate'          => $value['tax_rate'],
                'tax_free'          => $value['tax_free'],
                'price_tax'         => $price_tax,
                'price_vip_tax'     => $price_vip_tax,
                'price_total'       => $price_total,
                'price_vip_total'   => $price_vip_total,
                'is_combine_goods'  => $value['is_combine_goods'],
            ];
        }
        
        return Normal::returnCode(Normal::SUC,'获取成功',[
            'list'          => $data,
            'totalcount'    => $pageInfo['total']
        ]);
    }

    /**
     * 获取非组合装商品的销售税费
     * @param $price
     * @param $goods
     * @return float
     */
    public function singGoodsPriceFree($price,$goods){
        //反算税费
        $tax_rate = $goods['tax_rate'];
        $price_pay = round($price / 1,2);
        if($goods['high_price'] > 0 && $price_pay >= $goods['high_price']){
            $tax_rate = $goods['high_tax_rate'];
        }
        $goods['tax_rate'] = $tax_rate;
        $newPrice = round($price / (1 + $tax_rate),2);
        return round($price - $newPrice,2);
    }
}
